#include <vector>
#include <list>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
int n;
vector<vector < pair<int,double> >  >g;
vector<int> p;
vector<bool> u;
 
double EPS = 1E-10;
 
bool try_kuhn (int v, double gr) {
  if (u[v])  return false;
  u[v] = true;
  for (size_t i=0; i<g[v].size(); ++i)
    if (g[v][i].second <= gr + EPS) {
      int to = g[v][i].first;
      if (p[to] == -1 || try_kuhn (p[to], gr)) {
        p[to] = v;
        return true;
      }
    }
  return false;
}
 
vector<bool> u1;
 
bool matching (double gr) {
	fill(p.begin(), p.end(), -1);
	fill(u1.begin(), u1.end(), false);
  for (int i=0; i<n; ++i)
    for (size_t j=0; j<g[i].size(); ++j) {
      int to = g[i][j].first;
      if (g[i][j].second <= gr + EPS) {
        if (p[to] == -1) {
          p[to] = i;
          u1[i] = true;
          break;
        }
      }
    }
  for (int i=0; i<n; ++i) {
    if (u1[i])  continue;

	fill(u.begin(), u.end(), false);
    if (!try_kuhn (i, gr))
      return false;
  }
  return true;
}
 
double sqr (double a) {
  return a * a;
}
 
double dist (int ax, int ay, int bx, int by) {
  return sqrt  (sqr(ax-bx) + sqr(ay-by));
}
 
class FeudaliasWar {
public:
  double getMinimumTime(vector <int> baseX, vector <int> baseY, vector <int> siloX, vector <int> siloY, int takeOffTime, int rechargeTime, int missileSpeed) {
    n = (int) baseX.size();
    int m = (int) siloX.size();
	p.resize(n*m);
	u.resize(n);
	u1.resize(n);
	g.resize(n);

    int tm = 0;
    for (int i=0; i<n; ++i) {
      for (int j=0; j<n; ++j)
        for (int to=0; to<m; ++to) {
          double cur = dist (baseX[j], baseY[j], siloX[to], siloY[to]) / missileSpeed * 60 + tm + takeOffTime;
          int to_v = i * m + to;
          g[j].push_back (make_pair (to_v, cur));
          cerr << j+1 << ' ' << to+1 << ' ' << cur << endl;
        }
      tm += takeOffTime + rechargeTime * 60;
    }
    
    double l = 0,  r = 1E9;
    for (int i=0; i<150; ++i) {
      double mid = (l + r) / 2;
      if (matching (mid))
        r = mid;
      else
        l = mid;
    }
    return (l + r) / 2 / 60;
  }
};
 
 #define ARRSIZE(x) (sizeof(x)/sizeof(x[0]))

int main()
{
	{
		FeudaliasWar fw;
		int bx[]={0,2000,4000,6000,8000};
		int by[]={0,2000,4000,6000,8000};
		int sx[]={0,2000,4000,6000};
		int sy[]={2000,4000,6000,8000};

		vector<int> vbx(bx, bx+ARRSIZE(bx));
		vector<int> vby(bx, bx+ARRSIZE(by));
		vector<int> vsx(bx, bx+ARRSIZE(sx));
		vector<int> vsy(bx, bx+ARRSIZE(sy));
		
		double d=fw.getMinimumTime(vbx, vby, vsx, vsy, 60, 1000, 50);
		cout<< d <<endl;
	}
}